#ifndef __TIMER_H__
#define __TIMER_H__
#include <functional>
#include <queue>
#include <memory>
#include <vector>
#include <chrono>
#include <mutex>
#include <iostream>
#include <condition_variable>
#include <thread>
namespace mdk
{
    const int timer_default_wait = 300;

    enum class EM_TIMER_STATE
    {
        TIMER_STATE_ADD_TIMER = 0,
        TIMER_STATE_EXECUTE_TIMER,
    };

    enum class ENUM_WHILE_STATE
    {
        WHILE_STATE_CONTINUE = 0,
        WHILE_STATE_BREAK,
    };

    enum class ENUM_TIMER_TYPE
    {
        TIMER_TYPE_ONCE = 0,
        TIMER_TYPE_LOOP,
    };
    class TimerMgr;
    class Timer final
    {
    public:
        using Ptr = std::shared_ptr<Timer>;
        using WeakPtr = std::weak_ptr<Timer>;
        using Callback = std::function<void(void)>;

        Timer(std::string name,
              std::chrono::steady_clock::time_point startTime,
              std::chrono::nanoseconds lastTime,
              std::chrono::seconds delayTime,
              ENUM_TIMER_TYPE timertype,
              Callback &&callback);

        const std::chrono::steady_clock::time_point &getStartTime() const;
        const std::chrono::nanoseconds &getLastTime() const;
        std::chrono::nanoseconds getLeftTime();
        void cancel();
        ENUM_TIMER_TYPE get_timer_type();
        std::string getName();

    private:
        void operator()();
        std::string mTimerName;
        std::once_flag mExecuteOnceFlag;
        Callback mCallback;
        std::chrono::steady_clock::time_point mStartTime;
        std::chrono::nanoseconds mLastTime;
        std::chrono::seconds mDelayTime;
        ENUM_TIMER_TYPE mTimerType = ENUM_TIMER_TYPE::TIMER_TYPE_ONCE;

        friend class TimerMgr;
    };
}
#endif // !__TIMER_H__
